/**
* @brief 统一驱动: 基于温度传感器反馈的散热风扇恒温控制 PID 驱动
 * @author 张勇 41204@qq.com
 * @date 2022-04
*/

#pragma once

#include "mcu.h"
#include "unios.h"

typedef struct _unidrv_temp_fan_pid {
    float Kp;                           ///< 比例系数
    float Ki;                           ///< 积分系数
    float Kd;                           ///< 微分系数
    float integral;                     ///< 积分项累计值
    float prev_error;                   ///< 上一次误差
    float output_min;                   ///< 输出最小值(0%)
    float output_max;                   ///< 输出最大值(100%)
    float setpoint;                     ///< 目标温度
    float (*get_temperature)();         ///< 用于获取当前温度的函数
    void (*set_fan_speed)(float ratio); ///< 用于设置风扇转速(0-100%)的函数
    unios_task_t pidtask;               ///< 用于周期性运行 PID 调整的定时任务

    float alarm_error;                  ///< 失稳告警偏差(偏差超过此值则启动告警激活计时)
    uint32_t alarm_timeout_ms;          ///< 失稳告警激活时间(偏差超过 alarm_error 持续的时间超过此值，则告警)
    void (*alarm)(struct _unidrv_temp_fan_pid *pid); ///< 失稳告警: 持续多长时间(ms)后仍不能达到目标温度，则回调此函数
} unidrv_temp_fan_pid_t;

/// @brief PID 驱动启动
/// @param pid PID 驱动
/// @param Kp 比例系数
/// @param Ki 积分系数
/// @param Kd 微分系数
/// @param target_temperature 目标温度
std_err_t unidrv_temp_fan_pid_start(unidrv_temp_fan_pid_t *pid, float Kp, float Ki, float Kd, float target_temperature, uint32_t interval_ms);
